/**
**********************************************************************************************************************************************************************************************************************************
* @file:	StringList.h
* @author:	zinface
* @date:	2021年09月18日 16:56:02 星期六
* @brief:	FinaC 提供的 StringList 数据类型操作集
* 
* 1. createStringList(): 
* 2. stringListLength(StringList *): 
* 3. stringListAppend(StringList *, String *): 
* 4. stringListAppendCopy(StringList *, String *): 
**********************************************************************************************************************************************************************************************************************************
**/

// #ifndef __STRINGLIST__H__
// #define __STRINGLIST__H__

#include "FinalCType/StringList.h"

// FinalC_Object_Define(StringList) {
//     String *string;
//     StringList *next;
// };
FinalC_Object_Size(StringList);
#define self array->string
#define child array->next
#define parent array->parent

// #define FinalC_StringList_Func_Define(func) \
//     FinalC_Object_Func_Suffix(stringList, func)

// ------------------------------------ Constructor
/**
 * createStringList: 创建空的 StringList 对象实例
 *
 */
FINALC_WARN_UNUSED_RESULT
FinalC_Object_Create_Define(StringList) {
    StringList *array = (StringList*)calloc(StringListSize(), 1);
    self = NULL;
    child = NULL;
    parent = NULL;
    return array;
};

/**
 * createStringListWithString: 基于给定的 String 创建 StringList 对象实例
 *
 */
FINALC_WARN_UNUSED_RESULT
StringList *createStringListWithString(String *v) {
    StringList *array = createStringList();
    self = v;
    return array;
}

// ------------------------------------ Destructor

void destroyStringList(StringList *array) {
    if (array && child != NULL) destroyStringList(child);
    if (array && child != NULL) child = NULL;
    
    if (array && self != NULL) self = NULL;
    
    if (array) free(array);
    if (array) array = NULL;
}

void deleteStringListWithFunc(StringList *array, FinalCDeleteFunc deleteFunc) {
    finalc_stringlist_foreach(array, (FinalCFunc)deleteFunc, NULL);
    destroyStringList(array);
}

void deleteStringList(StringList *array) {
    deleteStringListWithFunc(array, (FinalCDeleteFunc)deleteString);
}

// ------------------------------------ Exstenstion Func: foreach
void finalc_stringlist_foreach(StringList *array, FinalCFunc func, void *data) {
    for (StringList *iter = array; iter; iter=iter->next) {
        if (func) func(iter->string, data);
    }
}

// ------------------------------------ Exstenstion Func: Length

int stringListLength(StringList *array) {
    if (array == NULL) return 0;
    int size = 0;
    for (StringList *iter = array; iter; iter = iter->next) {
        if (iter->string) size ++;
    }
    return size;
}

// ------------------------------------ Exstenstion Func: Last

StringList *stringListLast(StringList *array) {
    if (array == NULL) return NULL;
    int size = 0;
    StringList *iter = array;
    StringList *last = iter;
    for (; iter; iter = iter->next) {
        last = iter;
    }
    return last;
}

String *stringListLastString(StringList *array) {
    if (!stringListLast(array)) return NULL;
    return stringListLast(array)->string;
}

// ------------------------------------ Exstenstion Func: Append

FINALC_WARN_UNUSED_RESULT
StringList *FinalC_StringList_Func_Define(Prepend)(StringList *array, String *string) {
    if (!array)  array = createStringListWithString(string);
    else {
        parent = createStringListWithString(string);
        parent->next = array;
        return parent;
    }
    return array;
}

FINALC_WARN_UNUSED_RESULT
StringList *FinalC_StringList_Func_Define(Append)(StringList *array, String *string) {
    if (!array) {
        array = createStringListWithString(string);
    } else {
        stringListLast(array)->next = createStringListWithString(string);
    }
    return array;
}

// StringList *stringListAppendCopy(StringList *array, String *string) {
//     return array;
// }

// ------------------------------------ Exstenstion Func: String Split To StringList

FINALC_WARN_UNUSED_RESULT
StringList* createStringListWithSplit(const String *s, const char value) {
    StringList *array = NULL;

    List *list = stringSplit(s, value);
    for (List *iter = list; iter; iter=iter->next) {
        array = stringListAppend(array, (String*)iter->data);
    }
    destroyList(list);
    
    return array;
}
FINALC_WARN_UNUSED_RESULT
StringList* createStringListWithSplits(const String *s, const char *value) {
    StringList *array = NULL;

    List *list = stringSplits(s, value);
    for (List *iter = list; iter; iter=iter->next) {
        array = stringListAppend(array, (String*)iter->data);
    }
    destroyList(list);
    
    return array;
}
FINALC_WARN_UNUSED_RESULT
StringList* createStringListWithSplit_cnt(const String *s, const char value, int cnt) {
    StringList *array = NULL;

    List *list = stringSplit_cnt(s, value, cnt);
    for (List *iter = list; iter; iter=iter->next) {
        array = stringListAppend(array, (String*)iter->data);
    }
    destroyList(list);
    
    return array;
}

StringList* createStringListWithSplitAfter(String *v, const char value, afterdeleteString after) {
    StringList *array = createStringListWithSplit(v, value);
    if (after == deleteString || after == destroyString)
        after(v);
    return array;
}
StringList* createStringListWithSplitsAfter(String *v, const char *value, afterdeleteString after) {
    StringList *array = createStringListWithSplits(v, value);
    if (after == deleteString || after == destroyString)
        after(v);
    return array;
}
StringList* createStringListWithSplit_cntAfter(String *v, const char value, int cnt, afterdeleteString after) {
    StringList *array = createStringListWithSplit_cnt(v, value, cnt);
    if (after == deleteString || after == destroyString)
        after(v);
    return array;
}

// ------------------------------------ Exstenstion Func: Index
const StringList *FinalC_StringList_Func_Define(Index)(StringList *array, int index) {
    // int i = 0;
    // for (StringList *iter = array; iter; iter=iter->next) {
    //     if (i++ == index) return iter;
    // }
    while (index-- > 0 && array){
        array = child;
    }

    return array;
}

// #endif  //!__STRINGLIST__H__
